package com.example.mwavmedia.audio;

import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.text.TextUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * /storage/emulated/0/Android/data/com.example.mwavlearndemo/files/folder_audio/record.pcm
 * 测试路径pcm文件
 * 使用终端ffplay 播放即可
 * ffplay -f s16le -channels 2 -sample_rate 44100 record.pcm
 */
public class PcmRecorder {
    private RecordThread recordThread;
    public void startRecord(String path){
        stopRecord();
        recordThread = new RecordThread(path, MediaRecorder.AudioSource.MIC,
                44100,
                AudioFormat.CHANNEL_IN_STEREO,
                AudioFormat.ENCODING_PCM_16BIT);
        recordThread.start();
    }
    public void stopRecord(){
        if (recordThread == null) return;
        recordThread.stopRecording();//终止掉录音线程即可
        recordThread = null;
    }
    private static class RecordThread extends Thread{
        private AudioRecord audioRecord;
        private FileOutputStream fileOutputStream;

        private final String path;
        private final int audioSource;
        private final int sampleRateInHz;
        private final int channelConfig;
        private final int audioFormat;

        private int bufferSize;
        private boolean isStopRecord = false;

        public RecordThread(String path,
                            int audioSource,
                            int sampleRateInHz,
                            int channelConfig,
                            int audioFormat){
            this.path = path;
            this.audioSource = audioSource;
            this.sampleRateInHz = sampleRateInHz;
            this.channelConfig = channelConfig;
            this.audioFormat = audioFormat;
        }

        @Override
        public void run() {
            super.run();
            initIO();
            initAudioRecord();
            record();
        }
        private void initIO(){
            if (TextUtils.isEmpty(path)){
                return;
            }
            File file = new File(path);
            if (file.exists()) file.delete();
            try {
                fileOutputStream = new FileOutputStream(path);
            }catch (FileNotFoundException exception){
                exception.printStackTrace();
                exception = null;
            }
        }
        private void initAudioRecord(){
            bufferSize = AudioRecord.getMinBufferSize(sampleRateInHz,channelConfig,audioFormat);
            try {
                audioRecord = new AudioRecord(audioSource,sampleRateInHz,channelConfig,audioFormat,bufferSize);
            }catch (SecurityException securityException){
                securityException.printStackTrace();
            }

        }
        private void record(){
            if (audioRecord == null || fileOutputStream == null) return;
            byte[] data = new byte[bufferSize];
            audioRecord.startRecording();
            for (;;){
                if (isStopRecord){
                    release();
                    break;
                }
                int readSize = audioRecord.read(data,0,bufferSize);
                if (readSize <= 0){
                    isStopRecord = true;
                    continue;
                }
                try {
                    fileOutputStream.write(data);
                }catch (IOException ioException){
                    ioException.printStackTrace();
                }
            }
        }
        private void release(){
            if (audioRecord != null){
                audioRecord.stop();
                audioRecord.release();
                audioRecord = null;
            }
            if (fileOutputStream != null){
                try {
                    fileOutputStream.close();
                    fileOutputStream = null;
                }catch (IOException ioException){
                    ioException.printStackTrace();
                }
            }
        }
        void stopRecording(){
            isStopRecord = true;
           try {
               join(2000);
           }catch (InterruptedException interruptedException){
               interruptedException.printStackTrace();
           }
        }
    }
}
